package com.matt.service.impl;

import com.matt.domain.SaleFAQ;
import com.matt.foundation.constant.SaleFAQConstant;
import com.matt.foundation.vo.SalesFAQVo;
import com.matt.repository.SaleFAQRepository;
import com.matt.service.SaleFAQService;
import com.matt.service.remoteCall.SsoCallService;
import org.apache.commons.lang.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Describle This Class Is
 * @Author ZengMin
 * @Date 2018/12/12 16:55
 * @Company Matt
 */
@Service
public class SaleFAQServiceImpl implements SaleFAQService {

    @Autowired
    SaleFAQRepository saleFAQRepository;

    @Autowired
    private SsoCallService ssoCallService;
    
    @Override
    public Page<SaleFAQ> getPageList(String areaId,String keyWords ,Integer pageNum, Integer pageSize) {
        Specification<SaleFAQ> specification = new Specification<SaleFAQ>() {
            @Override
            public Predicate toPredicate(Root<SaleFAQ> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();

                Predicate p1 = criteriaBuilder.and(criteriaBuilder.equal(root.get("areaId"), areaId));
                Predicate p2 = criteriaBuilder.or(criteriaBuilder.isNull(root.get("areaId")));
                predicates.add(criteriaBuilder.or(p1, p2));
                
                Predicate p3 = criteriaBuilder.and(criteriaBuilder.equal(root.get("state"), SaleFAQConstant.SaleFAQType.APPROVED.codeOf()));
                Predicate p4 = criteriaBuilder.or(criteriaBuilder.isNull(root.get("state")));
                predicates.add(criteriaBuilder.or(p3, p4));
                
                
                predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("deleted"), false)));
                if (StringUtils.isNotBlank(keyWords))
                    predicates.add(criteriaBuilder.or(criteriaBuilder.like(root.get("question"), "%" + keyWords + "%"), criteriaBuilder.like(root.get("answer"), "%" + keyWords + "%")));
                
                query.where(predicates.toArray(new Predicate[predicates.size()]));
                query.orderBy(criteriaBuilder.desc(root.get("created")));
                return query.getRestriction();
            }
        };
        Page<SaleFAQ> SaleFAQPage = saleFAQRepository.findAll(specification, PageRequest.of(pageNum, pageSize));
        List<SalesFAQVo> list = Lists.newArrayList();
        SaleFAQPage.getContent().stream().forEach(o -> {       	       	
            list.add(SalesFAQVo.of(o));
        });

        return new PageImpl(list, PageRequest.of(pageNum, pageSize), SaleFAQPage.getTotalElements());
    }

    @Override
    public SaleFAQ getById(String id) {
        return saleFAQRepository.getOne(id);
    }

	@Override
	public SaleFAQ add(String areaId, String staffId, String staffName, String question, String answer) {
		
		SaleFAQ sf = new SaleFAQ();
		
		sf.setQuestion(question);
		sf.setAnswer(answer);
		sf.setAreaId(areaId);
		sf.setCreatorId(staffId);
        sf.setCreator(staffName);
		sf.setModifyed(staffId);
		sf.setModifyTime(new Date());
		sf.setState(SaleFAQConstant.SaleFAQType.TO_AUDIT.codeOf());
		
		return saleFAQRepository.save(sf);
	}

	@Override
	public Page<SaleFAQ> getPageListByStaffId(String staffId, Integer pageNum, Integer pageSize) {
		
		Specification<SaleFAQ> specification = new Specification<SaleFAQ>() {
            @Override
            public Predicate toPredicate(Root<SaleFAQ> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
               
                
                predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("creator"), staffId)));
                
                predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("deleted"), false)));
                
                
                query.where(predicates.toArray(new Predicate[predicates.size()]));
                query.orderBy(criteriaBuilder.desc(root.get("created")));
                return query.getRestriction();
            }
        };
		
        Page<SaleFAQ> SaleFAQPage = saleFAQRepository.findAll(specification, PageRequest.of(pageNum, pageSize));
        List<SalesFAQVo> list = Lists.newArrayList();
        SaleFAQPage.getContent().stream().forEach(o -> {
            list.add(SalesFAQVo.self(o));
        });

        return new PageImpl(list, PageRequest.of(pageNum, pageSize), SaleFAQPage.getTotalElements());
	}

	@Override
	public Page<SaleFAQ> getPageListByState(String areaId, Integer pageNum, Integer pageSize) {

		Specification<SaleFAQ> specification = new Specification<SaleFAQ>() {
            @Override
            public Predicate toPredicate(Root<SaleFAQ> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
               
                
                predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("areaId"), areaId)));
                
                predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("deleted"), false)));
                
                predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("state"), SaleFAQConstant.SaleFAQType.TO_AUDIT.codeOf())));
                
                
                query.where(predicates.toArray(new Predicate[predicates.size()]));
                query.orderBy(criteriaBuilder.desc(root.get("created")));
                return query.getRestriction();
            }
        };
		
        Page<SaleFAQ> SaleFAQPage = saleFAQRepository.findAll(specification, PageRequest.of(pageNum, pageSize));

        return SaleFAQPage;
	}

	@Override
	public SaleFAQ updateById(String id, Integer state,String staffId) {
		
		SaleFAQ sf = saleFAQRepository.getOne(id);
		
		sf.setState(state);
		sf.setModifyed(staffId);
		sf.setModifyTime(new Date());
		
		return saleFAQRepository.save(sf);
	}
}
